package com.infore.remoteControl.service.impl;

import java.util.Arrays;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.infore.remoteControl.constant.Constants;
import com.infore.remoteControl.constant.InstructionConstants;
import com.infore.remoteControl.constant.ResultConstants;
import com.infore.remoteControl.entity.instructionsEntity.InstructionsType;
import com.infore.remoteControl.enums.ResultStatus;
import com.infore.remoteControl.repository.IInstructionTypeRepository;
import com.infore.remoteControl.select.QueryDispatcher;
import com.infore.remoteControl.select.dto.QueryParamDto;
import com.infore.remoteControl.select.util.QueryUtil;
import com.infore.remoteControl.service.InstructionsTypeService;
import com.infore.remoteControl.util.MyBeanUtils;
import com.infore.remoteControl.util.PageUtil;
import com.infore.remoteControl.util.ResultEntity;

@Service
public class InstructionsTypeServiceImpl implements InstructionsTypeService {
	
	@Autowired
	QueryDispatcher queryDispatcher;
	
	@Autowired
	IInstructionTypeRepository iInstructionTypeRepository;

	@Override
	public ResultEntity query(QueryParamDto queryParamDto) {
		if (queryParamDto == null) { // 无查询条件
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS)
					.setDataList(iInstructionTypeRepository.findByOrderByCode());
		} else if (queryParamDto.getPageObject() != null && queryParamDto.getQueryCondition() == null
				&& queryParamDto.getAssembleCondition() == null && queryParamDto.getAssembleSql() == null) { // 无查询条件只分页
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(PageUtil.pageConvert(
					iInstructionTypeRepository.findByOrderByCode(queryParamDto.getPageObject().getPageRequest())));
		} else if (StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) { // 不指定任何字段
			return this.queryAll(queryParamDto);
		}
		return queryDispatcher.dispatcher(queryParamDto, InstructionsType.class);
	}

	@Override
	public ResultEntity edit(InstructionsType instructionsType) {
		if (StringUtils.isNotBlank(instructionsType.getInstructionsTypeId())) {
			InstructionsType oldInstructionsType = iInstructionTypeRepository.findById(instructionsType.getInstructionsTypeId()).orElse(null);
			// 判断根据传入的协议类型ID查询该数据是否存在
			if (oldInstructionsType != null) {
				// 查询原始对象将非空字段复制到保存对象的空字段上,避免更新操作的时候将空字段也修改了
				// MyBeanUtils.copyNonNullProperties匹配只针对单个对象,对于集合需要遍历匹配(协议数据为多个)
				MyBeanUtils.copyNonNullProperties(instructionsType, oldInstructionsType);
				instructionsType = oldInstructionsType;
			} else {
				return new ResultEntity(ResultStatus.ERROR, ResultConstants.NO_SUCH_OBJECT);
			}
		}
		//验证指令
		ResultEntity resultEntity = validate(instructionsType);
		if (resultEntity.getCode() == 1) {
			return resultEntity;
		}
		//保存或者更新数据
		iInstructionTypeRepository.save(instructionsType);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.DEAL_SUCCESS);
	}

	@Override
	public ResultEntity delete(String ids) {
		// 判断所传入的字符串是否包含逗号,如果包含则表示是删除多条记录
		if (ids.contains(",")) {
			List<String> idList = Arrays.asList(ids.split(","));
			iInstructionTypeRepository.deleteByInstructionsTypeIdIn(idList);
		} else {
			iInstructionTypeRepository.deleteById(ids);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.DELETE_SUCCESS);
	}

	@Override
	public ResultEntity validate(InstructionsType instructionsType) {
		//指令类型
		if ("".equals(instructionsType.getCode()) || instructionsType.getCode() == null) {
			return new ResultEntity(ResultStatus.ERROR,InstructionConstants.INSTRUCTIONTYPE_CODE_NULL);
		}else if (instructionsType.getCode().length() > 10) {
			return new ResultEntity(ResultStatus.ERROR,InstructionConstants.INSTRUCTIONTYPE_CODE_LENGTH);
		}else if (instructionsType.getName().equals("") || instructionsType.getName() == null) {
			return new ResultEntity(ResultStatus.ERROR,InstructionConstants.INSTRUCTIONTYPE_NAME_NULL);
		}else if (instructionsType.getName().length() > 20) {
			return new ResultEntity(ResultStatus.ERROR,InstructionConstants.INSTRUCTIONTYPE_NAME_LENGTH);
		}
		List<InstructionsType> insTypeNameList = iInstructionTypeRepository.findByName(instructionsType.getName());
		if (insTypeNameList != null && insTypeNameList.size() != 0) {
			return new ResultEntity(ResultStatus.ERROR, InstructionConstants.INSTRUCTIONTYPE_NAME_EXISTS);
		}
		List<InstructionsType> insTypeCodeList = iInstructionTypeRepository.findByCode(instructionsType.getCode());
		if (insTypeCodeList != null && insTypeCodeList.size() != 0) {
			return new ResultEntity(ResultStatus.ERROR, InstructionConstants.INSTRUCTIONTYPE_CODE_EXISTS);
		}
		return new ResultEntity(ResultStatus.SUCCESS,InstructionConstants.INSTRUCTION_SUCCESS);
	}
	
	// 不指定字段的通用查询
	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		return queryParamDto.getPageObject() != null // 判断是否分页
				? ResultEntity.page(iInstructionTypeRepository.findAll(new Specification<InstructionsType>() {
					@Override
					public Predicate toPredicate(Root<InstructionsType> root, CriteriaQuery<?> query,
							CriteriaBuilder criteriaBuilder) {
						// 构建查询条件
						List<Predicate> predicates = QueryUtil.createQueryCondition(queryParamDto, criteriaBuilder,
								root);
						// 组装查询条件
						Predicate predicate = QueryUtil.assembleCondition(queryParamDto, criteriaBuilder, predicates);
						// 组装SQL
						QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
						return query.getRestriction();
					}
				}, queryParamDto.getPageObject().getPageRequest()))
				: new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS)
						.setDataList(iInstructionTypeRepository.findAll(new Specification<InstructionsType>() {
							@Override
							public Predicate toPredicate(Root<InstructionsType> root, CriteriaQuery<?> query,
									CriteriaBuilder criteriaBuilder) {
								// 构建查询条件
								List<Predicate> predicates = QueryUtil.createQueryCondition(queryParamDto,
										criteriaBuilder, root);
								// 组装查询条件
								Predicate predicate = QueryUtil.assembleCondition(queryParamDto, criteriaBuilder,
										predicates);
								// 组装SQL
								QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
								return query.getRestriction();
							}
						}));
	}
}
